
/**
 * 项目命名空间
 * \代理layui.use、layui.define模块
 * \支持自有模块独立加载
 */
let Fa = function () {
    this.cache = {};
    this.modules = {};
    this.lisenter = {};
    this.options = {
        LOG_LEVEL: 0,//日志级别
    };
}
const fa = new Fa();

/**
 * 取内置模块
 * @param {*} name 
 * @package {*} onLoad
 */
Fa.prototype.load = function (name, onLoad) {
    if (this.cache[name]) {
        onLoad(this.cache[name]);
    }
    if (this.modules[name]) {
        this.lisenter[name] = this.lisenter[name] || [];
        this.lisenter[name].push((mod) => {
            onLoad(mod);
        });
    }
}

/**
 * 安装内置模块
 * 
 * @param {*} name 
 * @param {*} app 
 */
Fa.prototype.set = function (name, app) {
    this.cache[name] = app;
    (this.lisenter[name] || []).forEach(onLoad => onLoad(app));
}

/**
 * 声明是内置模块
 * 
 * @param {模块名称} name 
 */
Fa.prototype.inner = function (name) {
    this.modules[name] = true;
}
/**
 *  是否支持此模块
 * 
 * @param {模块名称} name 
 * @returns 支持返回true、否则false
 */
Fa.prototype.unSupport = function (name) {
    return !(this.cache[name] || this.modules[name]);
}
/**
 * 扩展layui.use、可以在单个文件中加载多个模块
 * @param {string\array} deps 
 * @param {function} callback 
 */
Fa.prototype.use = function (deps, callback) {
    if (typeof deps == "function") {
        callback = deps;
        deps = [];
    }
    deps = (typeof deps === 'string') ? [deps] : deps;
    let layuiDeps = deps.filter(dep => this.unSupport(dep));
    let faDeps = deps.filter(dep => !this.unSupport(dep));
    let count = faDeps.length;
    faDeps.forEach(dep => {
        this.load(dep, (mod) => {
            layui.dep = mod;
            count--;
        })
    });
    let tmp = setInterval(() => {
        if (count <= 0) {
            clearInterval(tmp);
            layui.use(layuiDeps, callback);
        }
    }, 5)
}
/**
 * 
 * @param {*} deps 
 * @param {*} callback 
 */
Fa.prototype.define = function (deps, callback) {
    if (typeof deps == 'function') {
        callback = deps;
        deps = [];
    }
    deps = (typeof deps === 'string') ? [deps] : deps;
    let layuiDeps = deps.filter((dep) => this.unSupport(dep));
    let faDeps = deps.filter((dep) => !this.unSupport(dep));
    this.use(faDeps, () => {//先加载内置模块
        layui.define(layuiDeps, (factory) => {//加载layui模块
            callback((app, exports) => {
                this.set(app, exports);
                factory(app, exports);
            });
        });
    });

}
Fa.prototype.config = function (options) {
    layui.each(options, (k) => { this.options[k] = options[k] });
    layui.config(options);
}